iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
Software Development

全端實戰心法:小團隊的產品開發大小事系列 第 7

登入系統(二):使用者密碼的傳遞及儲存,加密及雜湊

  • 分享至 

  • xImage
  •  

上一講我們聊到登入系統的常見登入機制,包含在自家做帳號密碼的比對來確認身份,或是使用第三方像是 Google 登入的服務。無論是哪一種類型,都需要在 Client 及 Server 間傳輸資訊,也基本上都需要自己的資料庫儲存使用者的資訊。

我們今天就來聊聊使用者資訊的傳遞及儲存,來探討密碼的加密與否、又該如何儲存密碼呢?

如何傳遞密碼?

先從密碼的傳遞來看,我們在登入的時候會在前端的頁面上輸入帳號及密碼,把這些資訊傳遞給後端的伺服器,由於 Client 和 Server 之間的連線是透過網際網路,中間經過無數的節點,只要有人在中間某個節點監聽封包,就有可能拿到我們所傳遞的資訊,這就是所謂的中間人攻擊

登入的 Request / Response 範例
*登入的 Request / Response 範例

因此,加密是必須的,而常見的加密方式是透過 HTTPS,我們其實無需特別為密碼或機敏資訊做處理,HTTPS 這個協定就會把要傳輸的帳號密碼加密後傳給 Server,並在 Server 端解密後拿到資訊,和資料庫中儲存的內容做比對來驗證身份。

而 HTTPS 加解密通訊行為則是透過「非對稱式加密」及「對稱式加密」兩種演算法組合,可以參考我之前寫的加密演算法,何謂對稱及非對稱式加密,來了解其基本原理。

HTTPS 加密登入的機敏資訊
*HTTPS 加密登入的機敏資訊

有了加密後的通訊機制,登入時傳遞的密碼和身份確認成功後回傳的 Token 或是 Session ID 就有了基本的保障了。

儲存密碼、確認使用者身份

在有了可靠的傳遞密碼機制後,我們便能夠在使用者送出登入 Request 後,用其所提供的帳號密碼來驗證身份。那麼問題是,驗證身份該如何達成呢?

最簡單暴力的方法,當然就是將每個使用者的 Username 和 Password 儲存在資料庫內,收到 Request 之後直接比對即可。

簡單的帳號密碼驗證範例
*簡單的帳號密碼驗證範例

然而,這樣的做法有個風險:

密碼以明碼儲存,當資料庫被洩露,其帳號密碼將能被「直接」拿來使用

什麼叫做能被直接拿來使用呢?就是一旦資料庫被駭客取得裡面的帳號密碼,就能夠直接用來登入你的網站,甚至其他更多網站,如果:你的某些用戶在多個網站都用同一組帳號密碼的話。

密碼的加密及雜湊

為了讓密碼的儲存更加安全,我們需要讓密碼變成無法直接使用的狀態,要達成這個目的,可以將密碼加密(Encryption)或是雜湊(Hashing)。

所謂的加密就是將明文轉變成密文,轉變的過程需要使用一把密鑰(Key);而理所當然的有加密就有解密,只要你擁有同一把密鑰,就能將密文反向轉變回原本的明文。

而雜湊的行為就和加密不太一樣了,雜湊也能將明文轉換成無法直接閱讀的一段 Value,稱做雜湊值(Hash Value),但這是不可逆的,一旦明文被轉換成雜湊值,要再找回原本的樣子就非常困難了。

加密及雜湊
*加密及雜湊

那麼,我們該儲存加密還是雜湊後的密碼呢?比較常見的做法是使用雜湊

因為相同的數值,雜湊後所得到的結果永遠相同,在比對密碼來驗證使用者的身份,使用雜湊值就已經足夠了。

只要當使用者在註冊或第一次被建立的時候先將密碼雜湊後儲存下來,接下來當使用者登入時傳來密碼,Server 只要用相同的雜湊算法再轉換一次,並且比對雜湊值有沒有符合資料庫的內容即可。

將密碼雜湊後比對資料庫儲存的雜湊值
*將密碼雜湊後比對資料庫儲存的雜湊值

對比加密算法,雖然也可以完成相同的需求,但是其風險就是我們需要多儲存一組密鑰。一旦資料庫被破解,同時間這組密鑰也被竊取,那麼其後果就和直接儲存密碼的明文一模一樣了。

但你可能會問,如果用戶忘記密碼的話怎麼辦?其實作法就是讓用戶重新設定一組密碼即可,如果伺服器有機會知道用戶的實際密碼是什麼,就肯定會有比較高的風險。


上一篇
登入系統(一):基本的登入機制
下一篇
登入系統(三):驗明身份,Session-Based 及 Token-Based 驗證
系列文
全端實戰心法:小團隊的產品開發大小事13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言